package com.kensure.shike.order.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import co.kensure.exception.BusinessExceptionUtil;
import co.kensure.frame.JSBaseService;
import co.kensure.mem.ArithmeticUtils;
import co.kensure.mem.CollectionUtils;
import co.kensure.mem.DateUtils;
import co.kensure.mem.MapUtils;
import co.kensure.mem.PageInfo;

import com.kensure.basekey.BaseKeyService;
import com.kensure.shike.baobei.model.SKBaobei;
import com.kensure.shike.baobei.model.SKBaobeiCB;
import com.kensure.shike.baobei.model.SKBaobeiYansePic;
import com.kensure.shike.baobei.service.SKBaobeiCBService;
import com.kensure.shike.baobei.service.SKBaobeiService;
import com.kensure.shike.baobei.service.SKBaobeiYansePicService;
import com.kensure.shike.order.dao.SKOrderDao;
import com.kensure.shike.order.model.SKFinPay;
import com.kensure.shike.order.model.SKOrder;
import com.kensure.shike.order.query.SKOrderQuery;
import com.kensure.shike.user.model.SKUser;
import com.kensure.shike.user.model.SKUserFR;
import com.kensure.shike.user.service.SKUserFRService;
import com.kensure.shike.user.service.SKUserSJYueService;
import com.kensure.shike.user.service.SKUserService;
import com.kensure.shike.zhang.model.SKUserZhang;
import com.kensure.shike.zhang.service.SKUserZhangService;

/**
 * 订单记录服务实现类
 * 
 * @author fankd created on 2019-6-12
 * @since
 */
@Service
public class SKOrderService extends JSBaseService {

	@Resource
	private SKOrderDao dao;
	@Resource
	private SKUserService sKUserService;
	@Resource
	private BaseKeyService baseKeyService;
	@Resource
	private SKBaobeiService sKBaobeiService;
	@Resource
	private SKBaobeiYansePicService sKBaobeiYansePicService;
	@Resource
	private SKOrderBackService sKOrderBackService;
	@Resource
	private SKUserZhangService sKUserZhangService;
	@Resource
	private SKFinPayService sKFinPayService;
	@Resource
	private SKBaobeiCBService sKBaobeiCBService;
	@Resource
	private SKUserFRService sKUserFRService;
	@Resource
	private SKUserSJYueService sKUserSJYueService;

	public SKOrder selectOne(Long id) {
		return dao.selectOne(id);
	}

	public List<SKOrder> selectByIds(Collection<Long> ids) {
		return dao.selectByIds(ids);
	}

	public List<SKOrder> selectByWhere(Map<String, Object> parameters) {
		return dao.selectByWhere(parameters);
	}

	public long selectCountByWhere(Map<String, Object> parameters) {
		return dao.selectCountByWhere(parameters);
	}

	public boolean insert(SKOrder obj) {
		super.beforeInsert(obj);
		if (obj.getYouhui() == null) {
			obj.setYouhui(0D);
		}
		obj.setTypeid(0);
		if (obj.getDjqse() == null) {
			obj.setDjqse(0D);
		}
		if (obj.getDbyue() == null) {
			obj.setDbyue(0D);
		}
		obj.setId(baseKeyService.getKey("sk_order"));
		return dao.insert(obj);
	}

	public boolean update(SKOrder obj) {
		super.beforeUpdate(obj);
		return dao.update(obj);
	}

	public boolean updateByMap(Map<String, Object> params) {
		return dao.updateByMap(params);
	}

	public boolean delete(Long id) {
		return dao.delete(id);
	}

	/**
	 * 销售数量和金额合计
	 * 
	 * @param parameters
	 * @return
	 */
	private Map<String, Object> sumByWhere(Map<String, Object> parameters) {
		return dao.sumByWhere(parameters);
	}

	/**
	 * 销售数量和金额合计，根据宝贝统计
	 * 
	 * @param parameters
	 * @return
	 */
	private List<Map<String, Object>> sumGroupBbidByWhere(Map<String, Object> parameters) {
		return dao.sumGroupBbidByWhere(parameters);
	}

	/**
	 * 宝贝销售数量
	 * 
	 * @param bbid
	 * @return
	 */
	public Map<String, Object> saleNum(Long bbid) {
		Map<String, Object> parameters = MapUtils.genMap("bbid", bbid);
		Map<String, Object> total = sumByWhere(parameters);
		if (total == null) {
			return MapUtils.genMap("sumbbnum", 0L);
		}
		Long sumbbnum = MapUtils.getMapLong(total, "sumbbnum");
		total.put("sumbbnum", sumbbnum);
		return total;
	}

	/**
	 * 30天内的营销数据
	 */
	public List<Map<String, Object>> yingxiaoshuju(Long bbid) {
		List<Map<String, Object>> mapList = new ArrayList<>();
		Date now = new Date();
		for (int day = 0; day < 30; day++) {
			Date date = DateUtils.getPastDay(now, -day);
			Map<String, Object> oneday = oneDaySale(date, bbid);
			mapList.add(oneday);
		}
		return mapList;
	}

	/**
	 * 30天内的某个商品营销数据
	 */
	public List<Map<String, Object>> yingxiaosp(Long bbid) {
		if (bbid == null) {
			BusinessExceptionUtil.threwException("必须选择商品编号");
		}
		SKBaobei bb = sKBaobeiService.selectOne(bbid);
		if (bb == null) {
			BusinessExceptionUtil.threwException("没有该商品");
		}
		List<Map<String, Object>> mapList = yingxiaoshuju(bbid);
		for (Map<String, Object> map : mapList) {
			map.put("title", bb.getTitle());
			Long totalSaleNum = (Long) saleNum(bbid).get("sumbbnum");
			map.put("totalSaleNum", totalSaleNum);
		}
		return mapList;
	}

	/**
	 * 某天的销售情况
	 */
	public Map<String, Object> oneDaySale(Date date, Long bbid) {
		String startTime = DateUtils.formatDateStart(date);
		String endTime = DateUtils.formatDateEnd(date);
		String day = DateUtils.format(date, DateUtils.DAY_FORMAT);
		Map<String, Object> parameters = MapUtils.genMap("startCreatedTime", startTime, "endCreatedTime", endTime);
		if (bbid != null) {
			parameters.put("bbid", bbid);
		}
		Map<String, Object> total = sumByWhere(parameters);
		Long sumbbnum = MapUtils.getMapLong(total, "sumbbnum");
		Double sumfenrun = MapUtils.getMapDouble(total, "sumfenrun");

		Map<String, Object> returnmap = MapUtils.genMap("id", day, "sumbbnum", sumbbnum, "sumfenrun", sumfenrun);
		return returnmap;
	}

	/**
	 * 一定时间内的销售详情
	 */
	public List<Map<String, Object>> yingxiaoxq(SKOrderQuery query, PageInfo page) {
		Map<String, Object> parameters = MapUtils.bean2Map(query, true);
		MapUtils.putPageInfo(parameters, page);
		List<Map<String, Object>> list = sumGroupBbidByWhere(parameters);
		for (Map<String, Object> total : list) {
			Long sumbbnum = MapUtils.getMapLong(total, "sumbbnum");
			Double sumfenrun = MapUtils.getMapDouble(total, "sumfenrun");
			total.put("sumbbnum", sumbbnum);
			total.put("sumfenrun", sumfenrun);
			Long id = MapUtils.getMapLong(total, "id");
			Long totalSaleNum = (Long) saleNum(id).get("sumbbnum");
			total.put("totalSaleNum", totalSaleNum);
		}
		return list;
	}

	/**
	 * 商品成本核算
	 */
	public List<Map<String, Object>> splrhs(SKOrderQuery query, PageInfo page) {
		Map<String, Object> parameters = MapUtils.bean2Map(query, true);
		MapUtils.putPageInfo(parameters, page);
		List<Map<String, Object>> list = sumGroupBbidByWhere(parameters);
		for (Map<String, Object> total : list) {
			Long sumbbnum = MapUtils.getMapLong(total, "sumbbnum");
			Double sumfenrun = MapUtils.getMapDouble(total, "sumfenrun");
			total.put("sumbbnum", sumbbnum);
			total.put("sumfenrun", sumfenrun);
			Long id = MapUtils.getMapLong(total, "id");
			Long totalSaleNum = (Long) saleNum(id).get("sumbbnum");
			total.put("totalSaleNum", totalSaleNum);
			// 成本单价
			Double cbPrice = 0D;
			SKBaobeiCB bbcb = sKBaobeiCBService.selectOne(id);
			if (bbcb != null) {
				cbPrice = bbcb.getJine();
			}
			total.put("cbPrice", cbPrice);
			// 成本金额
			Double cbjine = ArithmeticUtils.mul(cbPrice, sumbbnum, 2);
			// 毛利润
			Double lirun = ArithmeticUtils.sub(sumfenrun, cbjine);
			total.put("cbjine", cbjine);
			total.put("lirun", lirun);

			Double frjine = MapUtils.getMapDouble(total, "frjine");
			total.put("frjine", frjine);
			// 净利润
			Double jinlirun = ArithmeticUtils.sub(lirun, frjine);
			total.put("jinlirun", jinlirun);

		}
		return list;
	}

	// 新增订单
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void adds(List<SKOrder> orderList, SKFinPay finpay) {
		// 优惠率
		double youhuilv = 0D;
		if (finpay.getLeiji() != 0D) {
			youhuilv = ArithmeticUtils.div(finpay.getYouhui(), finpay.getLeiji(), 5);
		}
		for (SKOrder obj : orderList) {
			obj.setFinpayid(finpay.getId());
			double youhui = ArithmeticUtils.mul(youhuilv, obj.getTotal(), 2);
			obj.setYouhui(youhui);
			double fenrun = ArithmeticUtils.sub(obj.getTotal(), obj.getYouhui());
			obj.setFenrun(fenrun);
			obj.setTuihuan(fenrun);
			SKBaobeiYansePic one = sKBaobeiYansePicService.getOneByYanse(obj.getBbid(), obj.getYanse());
			obj.setContent(one.getContent());
			insert(obj);

		}
	}

	// 前端退货
	public void back(Long orderid, Integer typeid, String remark, String pics) {
		SKOrder order = detail(orderid);
		if (order.getBaobei().getKetui() != 1) {
			BusinessExceptionUtil.threwException("该商品不可退");
		}
		if (order.getDjqse() > 0) {
			BusinessExceptionUtil.threwException("代金券商品不可退");
		}
		SKUserFR fr = sKUserFRService.selectByOrderid(order.getFinpayid(), "DD");
		if (fr.getStatus() == 1) {
			BusinessExceptionUtil.threwException("该订单已经结算无法退货");
		}

		order.setTypeid(typeid);
		order.setRemark(remark);
		order.setHhTime(new Date());
		order.setStatus(1);
		update(order);
		if (StringUtils.isNotBlank(pics)) {
			String[] ps = pics.split(",");
			sKOrderBackService.add(ps, orderid);
		}
	}

	// 同意退货,换货
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public synchronized void tongYiBack(Long id) {
		SKOrder order = selectOne(id);
		if (order.getStatus() == 1) {
			SKFinPay finpay = sKFinPayService.selectOne(order.getFinpayid());
			SKUserFR fr = sKUserFRService.selectByOrderid(order.getFinpayid(), "DD");
			if (fr.getStatus() == 1) {
				BusinessExceptionUtil.threwException("该订单已经结算无法退货");
			}
			// 退货
			if (order.getTypeid() == 2) {
				tuiHuoZhang(order);
				// 换货
			} else {
				huanHuoZhang(order);
			}
			order.setStatus(9);
			update(order);

			// 如果都退货，关闭订单
			List<SKOrder> list = selectByFinpay(order.getFinpayid());
			boolean needClose = true;
			for (SKOrder temp : list) {
				if (temp.getStatus() != 9) {
					needClose = false;
					break;
				}
			}
			if (needClose) {
				sKFinPayService.close(order.getFinpayid());
			}

		}
	}

	/**
	 * 退货记帐
	 * 
	 * @param obj
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	private void tuiHuoZhang(SKOrder order) {
		SKUserZhang obj = new SKUserZhang();
		obj.setBusiid(order.getId());
		obj.setBusitypeid(103);
		obj.setYue(order.getTuihuan());
		obj.setUserid(order.getUserid());
		obj.setRemark(order.getTitle() + "退货");
		sKUserZhangService.add(obj);
		sKUserZhangService.commit(obj.getId());
		update(order);
	}

	/**
	 * 换货记帐
	 * 
	 * @param obj
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	private void huanHuoZhang(SKOrder order) {
		SKUserZhang obj = new SKUserZhang();
		obj.setBusiid(order.getId());
		obj.setBusitypeid(102);
		obj.setDbyue(order.getTuihuan());
		obj.setUserid(order.getUserid());
		obj.setRemark(order.getTitle() + "换货");
		sKUserZhangService.add(obj);
		sKUserZhangService.commit(obj.getId());
		update(order);
	}

	// 拒绝退货,换货
	public synchronized void juJueBack(Long id) {
		SKOrder order = selectOne(id);
		if (order.getStatus() == 1) {
			order.setStatus(2);
			update(order);
		}
	}

	/**
	 * 根据订单id获取订单详情
	 * 
	 * @param orderidList
	 * @return
	 */
	public SKOrder detail(Long id) {
		SKOrder order = selectOne(id);
		SKBaobei bb = sKBaobeiService.selectOne(order.getBbid());
		order.setBaobei(bb);
		return order;
	}

	// 初始化价格和总计
	public void initList(List<SKOrder> orderList, SKUser user,boolean isfree) {
		for (SKOrder obj : orderList) {
			obj.setBbnum(1);
			SKBaobei bb = sKBaobeiService.selectOne(obj.getBbid());
			double price = getPrice(obj);
			if(isfree){
				price = 0;
			}
			double total = ArithmeticUtils.mul(price, obj.getBbnum(), 2);
			obj.setTotal(total);
			obj.setStatus(0);
			obj.setSalePrice(price);
			obj.setUserid(user.getId());
			obj.setTitle(bb.getTitle());
			obj.setSjid(bb.getSjid());
			obj.setBaobei(bb);
		}
	}

	public Double getPrice(SKOrder obj) {
		SKBaobeiYansePic yanse = sKBaobeiYansePicService.getOneByYanse(obj.getBbid(), obj.getYanse());
		double price = yanse.getPrice();
		return price;
	}

	// 预览订单
	public void preView(List<SKOrder> orderList, SKUser user,boolean isfree) {
		initList(orderList, user,isfree);
	}

	// 获取配送方式
	public String peisong(List<SKOrder> orderList) {
		String peisong = "";
		for (SKOrder obj : orderList) {
			SKBaobei bb = sKBaobeiService.selectOne(obj.getBbid());
			String temp = bb.getPeisong();
			if (StringUtils.isNotBlank(peisong)) {
				if (!peisong.endsWith(temp)) {
					BusinessExceptionUtil.threwException("配送方式不一致，请分开下单");
				}
			}
			peisong = bb.getPeisong();
		}
		return peisong;
	}


	/**
	 * 通用，根据订单获取明细
	 */
	public List<SKOrder> selectByFinpay(Long finpayid) {
		Map<String, Object> parameters = MapUtils.genMap("finpayid", finpayid, "orderby", "id desc");
		List<SKOrder> list = selectByWhere(parameters);
		if (CollectionUtils.isNotEmpty(list)) {
			for (SKOrder order : list) {
				SKBaobei bb = sKBaobeiService.selectOne(order.getBbid());
				order.setBaobei(bb);
				SKBaobeiYansePic yansepic = sKBaobeiYansePicService.getOneByYanse(order.getBbid(), order.getYanse());
				order.setYansepic(yansepic);
			}
		}
		return list;
	}

	/**
	 * 根据状态查找用户的订单
	 * 
	 * @param status
	 * @param userid
	 * @return
	 */
	public List<SKOrder> selectByStatus(Integer startStatus, Long userid) {
		Map<String, Object> parameters = MapUtils.genMap("userid", userid, "startStatus", startStatus);
		return selectByWhere(parameters);
	}

	/**
	 * 根据用户的退货订单
	 * 
	 * @return
	 */
	public List<SKOrder> selectByStatus(Integer status) {
		Map<String, Object> parameters = MapUtils.genMap("status", status);
		return selectByWhere(parameters);
	}

	/**
	 * 增加代金券余额
	 */
	public void addDjq(Long finpayid) {
		List<SKOrder> orderlist = selectByFinpay(finpayid);
		for (SKOrder order : orderlist) {
			if (order.getDjqse() > 0) {
				sKUserSJYueService.updateYue(order.getUserid(), order.getSjid(), order.getDjqse());
			}
		}
	}

	/**
	 * 增加销量
	 */
	public void addXiaoLiang(Long finpayid) {
		List<SKOrder> orderlist = selectByFinpay(finpayid);
		for (SKOrder order : orderlist) {
			sKBaobeiYansePicService.addNum(order.getBbid(), order.getYanse());
		}
	}

	// 用代金券之后，分润数据进行修改
	@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
	public void djqfr(List<SKOrder> orderList) {
		for (SKOrder obj : orderList) {
			double fenrun = obj.getFenrun();
			obj.setDbyue(fenrun);
			obj.setFenrun(0D);
			update(obj);
		}
	}
}
